import React, { useState, useEffect } from 'react';
import { useTablePipeline } from 'ali-react-table';
import type { PopconfirmProps } from 'antd';
import { Popconfirm, Modal, Select, Spin, Input, Radio, Tooltip, message, Switch } from 'antd';
import _ from 'lodash';
import moment from 'moment';
import { manualStrategySaveDataStatus } from '../../../service';
import { TRDefault } from '@/components/index.js';
import {
  ApartmentOutlined,
  DeleteOutlined,
  CaretDownOutlined,
  PlusCircleOutlined,
} from '#/utils/antdIcons.js';
import { AntdBaseTable } from '@/base/TBaseTable';
import type {
  IDataListType,
  IDataSourceListType,
  IForecastAndSimulateDataType,
  IFormValue,
  IPostQueryForecastAndSimulateParamsType,
} from '../../../type';
import type { ISmoothStatusType } from '../../../type';
import { IUseType } from '../../../type';
import { smoothStatusOptions, defaultPointerNum } from '../../../dictionary';
import { TIME_ENUM } from '../../../tool';
// @ts-ignore
import { UserAndSimulate } from '../../../components/Charts/index';
import styles from './index.less';

const { confirm } = Modal;
interface IProps {
  /**
   * 数据
   */
  data?: IDataListType[];
  /**
   * 图表数据
   */
  userChartData?: IForecastAndSimulateDataType[];
  /**
   * 是否显示抽屉
   */
  visible?: boolean;
  /**
   * 平滑方式
   */
  smoothStatus?: ISmoothStatusType | null;
  /**
   * 默认平滑方式
   */
  defaultSmoothStatus?: (e: any) => void;
  /**
   * error
   */
  error?: boolean;
  /**
   * loading
   */
  loading?: boolean;
  /**
   * userLoading
   */
  userLoading?: boolean;
  /**
   * buttonLoading
   */
  buttonLoading?: boolean;
  /**
   * 预测源数据
   */
  dataSourceList?: IDataSourceListType[];
  /**
   * 装机量
   */
  defaultCapacity?: number | string;
  /**
   * ai测算loading
   */
  aiForecastIsLoading?: boolean;
  /**
   * 图形策略是否禁用
   */
  chartsForecastDisabled?: boolean;
  /**
   * ai测算是否禁用
   */
  aiForecastIsDisabled?: boolean;
  /**
   * 禁用保存按钮
   */
  saveButtonDisabled?: boolean;
  /**
   * AI策略
   */
  // onAiForecast?: () => void;
  /**
   * 重置
   */
  onReset?: (e?: any) => void;
  /**
   * 保存
   */
  onSave?: (data?: IDataListType[]) => void;
  /**
   * 改变平滑方式
   */
  onChangeSmoothWay?: (e: ISmoothStatusType) => void;
  /**
   * 编辑调整策略
   */
  onChange?: (data: IDataListType[], isRefresh?: boolean) => void;
  /**
   * 引用策略
   */
  onReferenceStrategy?: () => void;
  /**
   * 图形化策略
   */
  onReferenceChart?: () => void;
  /**
   * 请求数据
   */
  formValue?: IFormValue;
  /**
   * AI策略默认信参数
   */

  aiStrategyData?: any;
  /**
   * 开关状态
   */
  switchState?: boolean;
  /**
   * 开关状态方法
   */
  onChangeSwitchState?: (checked: boolean) => void;
}

const AdjustPolicyEditing = (props: IProps) => {
  const pointerNums = TIME_ENUM(defaultPointerNum);
  const {
    smoothStatus,
    error = false,
    loading = false,
    buttonLoading = false,
    aiForecastIsLoading = false,
    chartsForecastDisabled = false,
    aiForecastIsDisabled = false,
    saveButtonDisabled = false,
    data: _data = [],
    defaultCapacity,
    onChangeSmoothWay,
    onChange,
    onReset,
    onSave,
    dataSourceList = [],
    onReferenceStrategy,
    // onReferenceChart,
    formValue,
    aiStrategyData,
    userChartData = [],
    userLoading = false,
    visible,
    switchState,
    onChangeSwitchState,
    defaultSmoothStatus,
  } = props;
  const [correction, setCorrection] = useState<boolean>(aiStrategyData?.correction);
  const [data, setData] = useState<IDataListType[]>([]);
  const [isAdd, setIsAdd] = useState<boolean>(false);
  const [effectiveDate, setEffectiveDate] = useState<any>([
    aiStrategyData?.takeEffectStartTime && moment(aiStrategyData?.takeEffectStartTime),
    aiStrategyData?.takeEffectEndTime && moment(aiStrategyData?.takeEffectEndTime),
  ]);
  const [disabledSwitch, setDisabledSwitch] = useState<boolean>(
    !aiStrategyData?.state && !aiStrategyData?.takeEffectStartTime,
  ); //禁用按钮
  const defaultAdjustPolicyEditingRecord: IDataListType = {
    id: 1,
    dataSourceId: (dataSourceList[0]?.dataSourceId as number) || 0,
    minValue: '0.000',
    maxValue: defaultCapacity ?? '0.000',
    rateValue: '100',
    useType: IUseType.DATASOURCE,
    fixedValue: '0.000',
    beginTime: '',
    endTime: '',
    masterId: (dataSourceList[0]?.masterId as number) || 0,
  };
  const view_table = document.getElementById('view_table');

  /*  useEffect(() => {
    getBtnStuatus().then((status) => {
      onChangeSwitchState && onChangeSwitchState(status.switchState);
      defaultSmoothStatus && defaultSmoothStatus(status.smoothStatus);
    });
  }, [smoothStatus]); */

  useEffect(() => {
    if (_data) {
      setData(_data.length > 0 ? _data : [defaultAdjustPolicyEditingRecord]);
    }
  }, [_data, dataSourceList]);

  useEffect(() => {
    if (isAdd) {
      view_table?.scrollTo({
        top: view_table?.scrollHeight,
        behavior: 'smooth',
      });
    }
  }, [data]);

  const getBtnStuatus = async () => {
    const _params: IPostQueryForecastAndSimulateParamsType = {
      markDate: formValue?.calendarDate,
      stationId: formValue?.stationId ? Number(formValue.stationId) : undefined,
    };
    const res = await manualStrategySaveDataStatus(_params);
    return res;
  };

  const _onChangeSmoothStatus = (e: ISmoothStatusType) => {
    onChangeSmoothWay && onChangeSmoothWay(e);
  };

  const _onReset = () => {
    onReset && onReset();
  };

  const _onSave = () => {
    onSave && onSave();
  };

  const _onReferenceStrategy = () => {
    onReferenceStrategy && onReferenceStrategy();
  };

  const _onReferenceChart = () => {
    if (!chartsForecastDisabled) {
      // onReferenceChart && onReferenceChart();
    }
  };

  const onChangeValue = (e: any, record: IDataListType, key: string) => {
    let isUpdate: boolean = false;
    let arr = [...data];
    const regTime = /^[0-9]{0,4}$/;
    const regRate = /^[0-9]*$/;
    const regValue = /^[0-9]*(\.[0-9]*)?$/;
    if ((key === 'beginTime' || key === 'endTime') && !regTime.test(e.target.value)) {
      message.error('请输入正确的时间段');
      return;
    } else if (key === 'rateValue' && e?.target?.value && !regRate.test(e?.target?.value)) {
      return;
    } else if (
      (key === 'maxValue' || key === 'minValue' || key === 'fixedValue') &&
      e?.target?.value &&
      !regValue.test(e?.target?.value)
    ) {
      return;
    } else {
      isUpdate = true;
    }
    arr = arr.map((item) => {
      if (item.id === record.id) {
        return {
          ...item,
          [key]: key === 'useType' || key === 'dataSourceId' ? e : e.target.value,
        };
      }
      return { ...item };
    });
    setData(arr);
    setIsAdd(false);
    onChange && onChange(arr, isUpdate);
  };

  // 校验时间段是否正确
  const generaTime = (e: any, record: IDataListType, key: string) => {
    let arr: any[] = _.cloneDeep(data);
    const isReveal = Number(record.beginTime) > Number(record.endTime);
    const beginTime = isReveal ? record.endTime : record.beginTime;
    const endTime = isReveal ? record.beginTime : record.endTime;
    const beginIndex = pointerNums.findIndex((item) => item == beginTime);
    const endIndex = pointerNums.findIndex((item) => item == endTime);
    if (e.length < 4 || pointerNums.findIndex((item) => item == e) === -1) {
      arr = arr.map((item) => {
        if (item.id == record.id) {
          return {
            ...item,
            [key]: '',
          };
        }
        return { ...item };
      });
      message.error('您输入的时间段不符合规范');
      return;
    }
    if (!(record?.beginTime?.length && record?.endTime?.length)) {
      return;
    }
    arr = arr.map((item) => {
      if (!(item?.beginTime?.length && item?.endTime?.length)) {
        return { ...item };
      }
      if (record.id === item.id) {
        return {
          ...item,
          beginTime,
          endTime,
        };
      } else {
        // 如果时间段完全一样
        if (beginTime && endTime && item.beginTime >= beginTime && item.endTime <= endTime) {
          return undefined;
        } else if (
          (beginTime && endTime && beginTime <= item.endTime && endTime > item.endTime) ||
          (beginTime &&
            endTime &&
            beginTime <= item.endTime &&
            endTime <= item.endTime &&
            beginTime > item.beginTime)
        ) {
          if (beginIndex - 1 < 0) {
            return {
              ...item,
              beginTime: '',
            };
          }
          return {
            ...item,
            endTime: pointerNums[beginIndex - 1],
          };
        } else if (
          (endTime && endTime >= item?.beginTime && endTime < item.endTime) ||
          (endTime &&
            beginTime &&
            endTime >= item.beginTime &&
            endTime > item.endTime &&
            beginTime < item.beginTime)
        ) {
          if (endIndex + 1 > pointerNums.length - 1) {
            return {
              ...item,
              endTime: '',
            };
          }
          return {
            ...item,
            beginTime: pointerNums[endIndex + 1],
          };
        }
        return {
          ...item,
        };
      }
    });
    arr = arr.filter((item) => item);
    setData(arr);
    setIsAdd(false);
    onChange && onChange(arr);
  };

  const onBlurInput = (e: any, record: IDataListType, key: string) => {
    if (key === 'beginTime' || key === 'endTime') {
      generaTime(e.target.value, record, key);
    } else {
      let arr = [...data];
      arr = arr.map((item) => {
        if (item.id === record?.id) {
          let val = e?.target?.value;
          if (key == 'maxValue') {
            if (defaultCapacity && e.target.value > defaultCapacity) {
              val = Number(defaultCapacity)?.toFixed(3);
            } else if (e.target.value < Number(record?.minValue)) {
              val = Number(record?.minValue)?.toFixed(3);
            } else {
              val = Number(val)?.toFixed(3);
            }
          } else if (key === 'minValue') {
            val =
              e.target.value > Number(record?.maxValue)
                ? Number(record?.maxValue).toFixed(3)
                : Number(val)?.toFixed(3);
          } else if (key === 'fixedValue') {
            val =
              defaultCapacity && Number(e.target.value) > Number(defaultCapacity)
                ? Number(defaultCapacity)?.toFixed(3)
                : Number(val)?.toFixed(3);
          } else if (key === 'rateValue') {
            val = !val?.length ? 0 : Number(val) < 0 ? 0 : Number(val)?.toFixed(0);
          }
          return {
            ...item,
            [key]: val,
          };
        }
        return { ...item };
      });
      setData(arr);
      setIsAdd(false);
      onChange && onChange(arr);
    }
  };

  const onDelete = (record: IDataListType) => {
    confirm({
      title: '确定删除此行数据吗？',
      okText: '确认',
      cancelText: '取消',
      onOk: () => {
        const arr: any[] = data.filter((item) => {
          return item.id !== record.id;
        });
        setData(arr);
        setIsAdd(false);
        onChange && onChange(arr);
      },
    });
  };

  const onAdd = (record: IDataListType) => {
    // let position: any = record?.id;

    const position = data.findIndex((item) => item.id === record.id) + 1;

    const arr: any[] = [...data];

    const existingIds = new Set(arr.map((item) => item.id));

    let newId = 1;
    while (existingIds.has(newId)) {
      newId++;
    }

    const _obj = {
      ...defaultAdjustPolicyEditingRecord,
      id: newId,
      // id: (arr[arr.length - 1]?.id || 0) + 1,
    };
    // arr.push(_obj);
    arr.splice(position, 0, _obj);
    setData(arr);
    setIsAdd(true);
    onChange && onChange(arr);
  };

  const columns = [
    {
      code: 'beginTime',
      name: '时间段',
      align: 'center',
      width: 100,
      render(v: string, record: IDataListType) {
        return (
          <div className={styles.timeSlot}>
            <Input
              value={record.beginTime}
              onChange={(e) => {
                onChangeValue(e, record, 'beginTime');
              }}
              onBlur={(e) => {
                onBlurInput(e, record, 'beginTime');
              }}
            />
            -
            <Input
              value={record.endTime}
              onChange={(e) => {
                onChangeValue(e, record, 'endTime');
              }}
              onBlur={(e) => {
                onBlurInput(e, record, 'endTime');
              }}
            />
          </div>
        );
      },
    },
    {
      code: 'dataSourceId',
      name: (
        <div className={styles.dataSourceId}>
          <div className={styles.radio}>{''}</div>
          <div className={styles.ratio}>调整比例(%)</div>
          <div className={styles.predictSource}>基准预测源</div>
          <div className={styles.maxNum}>最大值</div>
          <div className={styles.minNum}>最小值</div>
        </div>
      ),
      width: 325,
      render(v: string, record: IDataListType) {
        return (
          <div className={styles.dataSourceIdShow}>
            <div className={styles.ratio}>
              <Radio
                checked={record?.useType === IUseType.DATASOURCE}
                onClick={() => onChangeValue(IUseType.DATASOURCE, record, 'useType')}
              />
              <Input
                style={{
                  marginLeft: 6,
                }}
                value={record?.rateValue}
                disabled={record?.useType != IUseType.DATASOURCE}
                onChange={(e) => {
                  onChangeValue(e, record, 'rateValue');
                }}
                onBlur={(e) => {
                  onBlurInput(e, record, 'rateValue');
                }}
              />
            </div>
            <div className={styles.predictSource}>
              <Select
                value={record?.dataSourceId ? record?.dataSourceId : undefined}
                disabled={record?.useType != IUseType.DATASOURCE}
                optionLabelProp="label"
                bordered={false}
                suffixIcon={<CaretDownOutlined />}
                onChange={(e) => onChangeValue(e, record, 'dataSourceId')}
                dropdownClassName={styles.selectDown}
              >
                {dataSourceList.map((item, index) => {
                  return (
                    <Select.Option
                      key={index}
                      value={item?.dataSourceId || 0}
                      label={item?.dataSourceName}
                    >
                      <div className={styles.options}>
                        {index === 0 && <span className={styles.iconbox}>主</span>}
                        <Tooltip placement="topLeft" title={item?.dataSourceName}>
                          <span className={styles.size}>{item?.dataSourceName || ''}</span>
                        </Tooltip>
                      </div>
                    </Select.Option>
                  );
                })}
              </Select>
            </div>
            <div className={styles.maxNum}>
              <Input
                value={record?.maxValue}
                disabled={record?.useType != IUseType.DATASOURCE}
                onChange={(e) => {
                  onChangeValue(e, record, 'maxValue');
                }}
                onBlur={(e) => {
                  onBlurInput(e, record, 'maxValue');
                }}
              />
            </div>
            <div className={styles.minNum}>
              <Input
                value={record?.minValue}
                disabled={record?.useType != IUseType.DATASOURCE}
                onChange={(e) => {
                  onChangeValue(e, record, 'minValue');
                }}
                onBlur={(e) => {
                  onBlurInput(e, record, 'minValue');
                }}
              />
            </div>
          </div>
        );
      },
    },
    {
      code: 'fixedValue',
      name: (
        <div className={styles.fixedValue}>
          <div className={styles.name}>固定值</div>
        </div>
      ),
      width: 110,
      render(v: string, record: IDataListType) {
        return (
          <div className={styles.fixedValueShow}>
            <div className={styles.radio}>
              <Radio
                checked={record?.useType === IUseType.FIXATION}
                onClick={() => onChangeValue(IUseType.FIXATION, record, 'useType')}
              />
            </div>
            <div className={styles.fixedValueShowInput}>
              <Input
                value={record?.fixedValue}
                disabled={record?.useType != IUseType.FIXATION}
                onChange={(e) => {
                  onChangeValue(e, record, 'fixedValue');
                }}
                onBlur={(e) => {
                  onBlurInput(e, record, 'fixedValue');
                }}
              />
            </div>
          </div>
        );
      },
    },
    {
      code: 'operation',
      name: '操作',
      width: 60,
      align: 'center',
      render(v: string, record: IDataListType) {
        return (
          <div className={styles.operation}>
            <div className={styles.oDel}>
              <DeleteOutlined twoToneColor="#eb5757" onClick={() => onDelete(record)} />
            </div>
            <div className={styles.oAdd}>
              <PlusCircleOutlined onClick={() => onAdd(record)} />
            </div>
          </div>
        );
      },
    },
  ];

  const pipeline = useTablePipeline({})
    .input({ dataSource: data, columns: columns as any })
    .primaryKey('id')
    .appendRowPropsGetter((): any => {
      const color = '#222629';
      return {
        style: { '--bgcolor': color, '--hover-bgcolor': color },
      };
    });

  const onStrategyChange = (checked: boolean, correction: boolean) => {
    onChangeSwitchState && onChangeSwitchState(checked);
  };

  //
  const confirmPopconfirm: PopconfirmProps['onConfirm'] = (e) => {
    onChangeSwitchState && onChangeSwitchState(true);
  };

  return (
    <div className={styles.container}>
      <div className={styles.middle}>
        <div className={styles.select}>
          <div className={styles.selectTitle}>平滑：</div>
          <Select
            value={smoothStatus ?? (smoothStatusOptions[2].value as ISmoothStatusType)}
            options={smoothStatusOptions as any}
            suffixIcon={<CaretDownOutlined />}
            bordered={false}
            onChange={_onChangeSmoothStatus}
          />
        </div>
        <div className={styles.strategySwitch}>
          <div className={styles.policyReferences} onClick={_onReferenceStrategy}>
            <ApartmentOutlined className={styles.policyReferencesLogo} />
            <span className={styles.aiForecastText}>策略引用</span>
          </div>
          <div className={formValue?.provinceId === '37' ? styles.nodSdSwitch : styles.sdSwitch}>
            <div className={styles.line} />
            {switchState ? (
              <Switch
                style={{ marginRight: 8, marginLeft: 8 }}
                checked={switchState}
                // disabled={disabledSwitch}
                onChange={(e) => {
                  // onChangeSwitchState && onChangeSwitchState(e);
                  onStrategyChange(e, correction);
                }}
              />
            ) : (
              <Popconfirm
                title="注意: 启用AI将覆盖人工调整策略!"
                onConfirm={confirmPopconfirm}
                okText="确认"
                cancelText="取消"
              >
                <Switch
                  style={{ marginRight: 8, marginLeft: 8 }}
                  checked={switchState}
                  // disabled={disabledSwitch}
                  /* onChange={(e) => {
              // onChangeSwitchState && onChangeSwitchState(e);
              onStrategyChange(e, correction);
            }} */
                />
              </Popconfirm>
            )}
            启用AI策略
          </div>
        </div>
      </div>
      <div className={styles.content}>
        {loading ? (
          <Spin />
        ) : error ? (
          <TRDefault type={'emptysm'} message={'暂无数据'} />
        ) : (
          <div className={styles.bottom}>
            <div className={styles.table}>
              <div className={styles.antdBaseTable} id="view_table">
                <AntdBaseTable
                  useVirtual={{ horizontal: true, vertical: true, header: false }}
                  style={{
                    '--row-height': '28px',
                    // '--header-bgcolor': '#383C3E',
                    '--header-row-height': '28px',
                    '--cell-padding': '4px 16px',
                    // '--cell-border-vertical': '1px solid #4E5154',
                    // '--header-cell-border-vertical': '1px solid #4E5154',
                    '--hover-bgcolor': '#222629',
                  }}
                  {...pipeline.getProps()}
                />
              </div>
            </div>
            <div className={styles.content}>
              {userLoading ? (
                <Spin />
              ) : userChartData.length > 0 ? (
                <div className={styles.charts}>
                  <UserAndSimulate data={userChartData} date={formValue?.calendarDate} />
                </div>
              ) : (
                <TRDefault type={'emptysm'} message={'暂无数据'} />
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default AdjustPolicyEditing;
